package org.jeecg.modules.ywMaterialEnter.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.constant.CommonConstant;
import org.jeecg.constant.InventoryConstant;
import org.jeecg.modules.ywMaterialEnter.entity.YwMaterialEnterMain;
import org.jeecg.modules.ywMaterialEnter.entity.YwMaterialEnterDetail;
import org.jeecg.modules.ywMaterialEnter.mapper.YwMaterialEnterDetailMapper;
import org.jeecg.modules.ywMaterialEnter.mapper.YwMaterialEnterMainMapper;
import org.jeecg.modules.ywMaterialEnter.service.IYwMaterialEnterDetailService;
import org.jeecg.modules.ywMaterialEnter.service.IYwMaterialEnterMainService;
import org.jeecg.modules.ywMaterialInventory.entity.YwMaterialInventoryInfo;
import org.jeecg.modules.ywMaterialInventory.service.IYwMaterialInventoryInfoService;
import org.jeecg.modules.ywSemiFinishedProductEnter.entity.YwSemiFinishedProductEnterDetail;
import org.jeecg.modules.ywSemiFinishedProductEnter.entity.YwSemiFinishedProductEnterMain;
import org.jeecg.modules.ywSemiFinishedProductInventory.entity.YwSemiFinishedProductInventoryInfo;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;

/**
 * @Description: 材料入库
 * @Author: jeecg-boot
 * @Date: 2024-08-22
 * @Version: V1.0
 */
@Service
public class YwMaterialEnterMainServiceImpl extends ServiceImpl<YwMaterialEnterMainMapper, YwMaterialEnterMain> implements IYwMaterialEnterMainService {

    @Resource
    private YwMaterialEnterMainMapper ywMaterialEnterMainMapper;
    @Resource
    private YwMaterialEnterDetailMapper ywMaterialEnterDetailMapper;
    @Resource
    private IYwMaterialEnterDetailService ywMaterialEnterDetailService;
    @Resource
    private IYwMaterialInventoryInfoService ywMaterialInventoryInfoService;

    @Override
    @Transactional
    public void saveMain(YwMaterialEnterMain ywMaterialEnterMain, List<YwMaterialEnterDetail> ywMaterialEnterDetailList) {
        Assert.notEmpty(ywMaterialEnterDetailList, "入库单数据异常,请填写入库单详情！");
        ywMaterialEnterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.CREATE_END.getCode());
        ywMaterialEnterMainMapper.insert(ywMaterialEnterMain);

        for (YwMaterialEnterDetail entity : ywMaterialEnterDetailList) {
            entity.setEnterId(ywMaterialEnterMain.getId());
            entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
            ywMaterialEnterDetailMapper.insert(entity);
        }
    }

    @Override
    public Result<?> confirmEnter(String id) {
        YwMaterialEnterMain enterMain = this.ywMaterialEnterMainMapper.selectById(id);
        Assert.notNull(enterMain, "入库单数据异常,请联系管理员！");
        Assert.isFalse(InventoryConstant.EnterStatusEnum.DELETE.getCode().equals(enterMain.getEnterStatus()), "入库单状态异常,请联系管理员！");
        List<YwMaterialEnterDetail> enterDetailList = ywMaterialEnterDetailService.selectList(id);
        Assert.notEmpty(enterDetailList, "入库单数据异常,请联系管理员！");

        long errorDataCount = enterDetailList.stream().filter(data -> data.getEnterWeight().compareTo(BigDecimal.ZERO) < 0).count();
        Assert.isTrue(errorDataCount == 0, "入库重量不能小于0！");

        // 封装库存信息
        List<YwMaterialInventoryInfo> inventoryInfoList = new ArrayList<>();
        for (YwMaterialEnterDetail enterDetail : enterDetailList) {
            YwMaterialInventoryInfo inventoryInfo = getYwMaterialInventoryInfo(enterDetail, enterMain);
            inventoryInfoList.add(inventoryInfo);
        }
        // 更新主表主库状态
        enterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.ENTER_END.getCode());
        this.ywMaterialEnterMainMapper.updateById(enterMain);

        // 更新库存
        ywMaterialInventoryInfoService.saveBatch(inventoryInfoList);

        return Result.OK("入库成功！");
    }

    @NotNull
    private static YwMaterialInventoryInfo getYwMaterialInventoryInfo(YwMaterialEnterDetail enterDetail, YwMaterialEnterMain enterMain) {
        YwMaterialInventoryInfo inventoryInfo = new YwMaterialInventoryInfo();
        inventoryInfo.setEnterId(enterMain.getId());
        inventoryInfo.setEnterDate(enterMain.getEnterDate());
        inventoryInfo.setBillNo(enterDetail.getBillNo());
        inventoryInfo.setProductCode(enterDetail.getProductCode());
        inventoryInfo.setProductName(enterDetail.getProductName());
        inventoryInfo.setInventoryWeight(enterDetail.getEnterWeight());
        inventoryInfo.setInventoryVolume(enterDetail.getTotalVolume());
        inventoryInfo.setGoodsPosition(enterDetail.getGoodsPosition());
        inventoryInfo.setManufactureDate(enterDetail.getManufactureDate());
        inventoryInfo.setStatus(CommonConstant.StatusEnum.YES.getCode());
        return inventoryInfo;
    }

    @Override
    @Transactional
    public void updateMain(YwMaterialEnterMain ywMaterialEnterMain, List<YwMaterialEnterDetail> ywMaterialEnterDetailList) {
        Assert.notEmpty(ywMaterialEnterDetailList, "入库单数据异常,请填写入库单详情！");
        ywMaterialEnterMainMapper.updateById(ywMaterialEnterMain);

        ywMaterialEnterDetailMapper.deleteByMainId(ywMaterialEnterMain.getId());

        for (YwMaterialEnterDetail entity : ywMaterialEnterDetailList) {
            entity.setId(null);
            entity.setEnterId(ywMaterialEnterMain.getId());
            entity.setStatus(CommonConstant.StatusEnum.YES.getCode());
            entity.setCreateTime(null);
            entity.setCreateBy(null);
            ywMaterialEnterDetailMapper.insert(entity);
        }
    }

    @Override
    @Transactional
    public void delMain(String id) {
        // 更新子表有效标志
        ywMaterialEnterDetailMapper.deleteByMainId(id);

        // 更新主表有效标志
        YwMaterialEnterMain enterMain = new YwMaterialEnterMain();
        enterMain.setId(id);
        enterMain.setEnterStatus(InventoryConstant.EnterStatusEnum.DELETE.getCode());
        ywMaterialEnterMainMapper.updateById(enterMain);
    }

    @Override
    @Transactional
    public void delBatchMain(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            this.delMain(id.toString());
        }
    }

}
